// /////////////////////////////////////////////////////////////////////////////
//
// Name:            ScriptManager.h
// Author:          Michael Bartsch (ZCCdark203)
//
// Desc :           Declaration of the ScriptManager class.
//
// License:         Copyright (C) 2009 Michael Bartsch and Contributors
//
//                  This program is free software: you can redistribute it
//                  and/or modify it under the terms of the zlib/libpng License.
//                  See main.cpp for conditions of distribution and use.
//
// /////////////////////////////////////////////////////////////////////////////

#ifndef __SCRIPTMANAGER_H__
#define __SCRIPTMANAGER_H__

// Include files
#include "../dependencies.h"
#include "../core/ReferenceCounted.h"

#ifdef __COMPILE_WITH_ANGELSCRIPT__

#include "Script.h"

// Forward declarations.
class Script;


// ScriptManager class
//! The Script Manager is the central interface point to all script related functions of this
//! program.
class ScriptManager : public ReferenceCounted
{
    friend class Script;

public:

    // Initialisation and deinitialisation
    //! Constructor
    ScriptManager();
    //! Deconstructor
    ~ScriptManager();

    //! Initialises the ScriptManager.
    void init();
    //! Clears the ScriptManager.
    void clear();

    // Reference counting
    //! Increases the reference counter.
    //! @note This is a dummy function.
    void grab();
    //! Decreases the reference counter.
    //! @note This is a dummy function.
    void drop();

    // Methods
    //! Returns a direct pointer to the AngelScript engine.
    //! @note Not available in AngelScript.
    asIScriptEngine* getEngine() const;

    //! Adds the given Script to the ScriptManager
    //! @param script        Pointer to the Script to add.
    //! @return True if addition was successful, false if addition was a failure.
    bool addScript(Script *script);

    //! Adds a script section to the ScriptManager.
    //! These script sections are added to all scripts.
    //! @param name          Name of the script section.
    //! @param section       Contents of the section.
    bool addScriptSection(const std::string &name, const std::string &section);

    //! Creates (and adds) an script with the given name.
    //! @param name          Name of the script.
    //! @param grab          Should the ScriptManager add the loaded script to the internal list?
    //! @return Pointer to the Script on success, NULL on failure.
    Script* createScript(const std::string &name, bool grab = true);
    //! Creates an script with the given name, loaded from the given file.
    //! @param fileName      Filename of the file to load.
    //! @param grab          Should the ScriptManager add the loaded script to the internal list?
    //! @return Pointer to the Script on success, NULL on failure.
    Script* createScriptFromFile(const std::string &fileName, bool grab = true);
    //! Creates an script with the given name, loaded from the given file.
    //! @param file          Pointer to the IReadFile that will be used.
    //! @param grab          Should the ScriptManager add the loaded script to the internal list?
    //! @return Pointer to the Script on success, NULL on failure.
    Script* createScriptFromFile(IReadFile *file, bool grab = true);

    //! Gets the Script with the given ID.
    //! @return Pointer to the Script if found, else NULL.
    Script* getScript(const u32 id);
    //! Gets the Script with the given name.
    //! @return Pointer to the Script if found, else NULL.
    Script* getScript(const std::string &name);

    //! Removes all scripts from the ScriptManager.
    void removeScripts();
    //! Removes all script sections from the ScriptManager.
    void removeScriptSections();
    //! Removes the given Script.
    //! @param script        Pointer to the Script to remove.
    //! @return True if removal was successful, false if removal was a failure.
    bool removeScript(Script *script);
    //! Removes the given Script with the given ID.
    //! @param id            ID of the Script to remove.
    //! @return True if removal was successful, false if removal was a failure.
    bool removeScript(const u32 id);
    //! Removes the given Script with the given name.
    //! @param name          Name of the Script to remove.
    //! @return True if removal was successful, false if removal was a failure.
    bool removeScript(const std::string &name);
    //! Removes the script section with the given name.
    //! @param name          Name of the script section to remove.
    bool removeScriptSection(const std::string &name);
	//! Register all script side globals and helpers
	void bindGlobals();

private:

    // Private methods.
    void addScriptSectionsToScript(Script *script);

    // Private members
    asIScriptEngine *pEngine;

    std::vector<Script*> mScripts;
    std::map<std::string, std::string> mScriptSections;
};


// AngelScript functions
//! Implements a message callback function for AngelScript.
extern void asMessageCallback(const asSMessageInfo *msg, void *param);

//! Implements a way to output a message.
extern void asEcho(const std::string &msg);

#endif // __COMPILE_WITH_ANGELSCRIPT__

#endif
